<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    /*
       13个指令  v-cloak v-html v-text v-pre v-once v-bind v-on v-model v-if v-shou v-esle if v-esle  v-for   		
       生命周期  create mount update destory active   10个 常用8个   
            
       vue-resource(2.0以后未更新)  vue-axios   ajax的部分

       style  lang=“less”即可  仍然穿透 deep v-deep +    /deep/    :deep

---------------------------------------------------------------------------------------
分别简述computed和watch的使用场景
答：computed:
　　　　当一个属性受多个属性影响的时候就需要用到computed
　　　　最典型的例子： 购物车商品结算的时候
       watch:
　　　　当一条数据影响多条数据的时候就需要用watch
　　　　例子：搜索数据
------------------------------------------------------------------------------------------过滤器操作
什么是过滤器？
	//数据渲染到页面上进行的最后一次操作     比如验证码的过滤 
  过滤 filter
  局部
    new Vue({
        filters:{
            name(data,arguments1,arguments2){}
        }
    })
  全局
    Vue.filter(name,function(data,arguments1,arguments2){})
    全局和局部过滤器同命时 会使用局部的过滤器

--------------------------------------------------------------------------------------------自定义指令
指令 directive
   局部
        简单化定义
            new Vue({
                directives:{    //1元素，2参数，3old node，4new node，
                    name(dom,arguments,newvnode,oldvnode){
                    }
                }
            })
        生命周期
        new Vue({
            directives:{
                name:{
                bind(dom,arguments,newvnode,oldvnode){},                         // 创建ok后的概念      
                inserted(dom,arguments,newvnode,oldvnode){},                     //  渲染ok 初始化
                update(dom,arguments,newvnode,oldvnode){},                       //  改变了触发 发生之前
                componentUpdated(dom,arguments,newvnode,oldvnode){},             // 视图更新之后
                unbind(dom,arguments,newvnode,oldvnode){}                        // 同生命周期销毁    不常用优化会用到 
                }
            }
        })

   全局
        简单化定义
            Vue.directive(name,function(dom,arguments,newvnode,oldvnode){
            }) 
自定义指令有五个生命周期（也叫钩子函数），分别是 bind,inserted,update,componentUpdated,unbind 
bind                   只调用一次，指令第一次绑定到元素时调用，用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
inserted               被绑定元素插入父节点时调用（父节点存在即可调用，不必存在于document中）。
update                 被绑定于元素所在的模板更新时调用，而无论绑定值是否变化。通过比较更新前后的绑定值，可以忽略不必要的模板更新。
componentUpdated:      被绑定元素所在模板完成一次更新周期时调用。
unbind                 只调用一次，指令与元素解绑时调用。

-----------------------------------------------------------------------------------------动画使用操作-----------------------------------
动画F
       4步 
	  条件渲染 (使用 v-if)
              条件展示 (使用 v-show)
                   动态组件
              组件根节点 ！！

-----------------------------------------------------------------------------------------组件使用规范-------------------------------------
组件的两种定义方式    component & extends   
局部&全局          	       		
            //组件是社么？
	        //vue最强的的功能之一可以拓展html元素 封装重用的代码 
	       	//组件是可复用的Vue实例，且带有一个名字(命名规范)
                                                                //组件必须搁vue实例上面 否则没报错没效果                                                                           
               Vue.component('name',{                           //每一个组件就像是一个单独的vue 实例  vue有的它都有 
			template:'',	 //这里是组件的模板可以抽离出去用于内容多的情况  用id链接 抽离出去的组件模板用一个div包裹方便维护
			data(){		     //组件里面的data是一个方法必须有return类似vue示例的methods
				return {					
				}
			}
		})

组件的命名规范  
                    //  官方强烈推荐要遵循W3C规范的自定义组件名，即组件名称全部使用小写字母且
                    //  组件名称可以使用驼峰命名法，但是在使用的时候必须大写转小写，且用 - 连接
---------------------------局部组件
			new Vue({
				el: '#app',
				data: {},
				components: {
					"com1": com1,   //把子组件抽离出去
					"com2": {
						template: "<div>这个是子组件儿  </div>",
						data: {},
						methods: {}
					}
				}
			})
<body>
	<div id="app">
	    <com1></com1>
	    <com2></com2>
	</div>
</body>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>

		<template id="com1">
			<div>
				<div>这是子组件</div>
			</div>                     
		</template>
		// 给组件命名不可以 用html标签     驼峰命名法(-链接)    语义化    用大盒子包裹方便运维 ，
		<script type="text/javascript">			 		
			var com1 = {                                 //抽离出的组件 所对应的变量
				template: "#com1",
				data() {
					return {
					}
				},
				methods: {}
			}
			new Vue({
				el: '#app',
				data: {},
				components: {
					"com1": com1,  //把子组件抽离出去
					"com2": {
						template: "<div>这个是子组件儿  </div>",
						data: {},
						methods: {}
					}
				}
			})
</script>
--------------------------------------------------------------------------------------------------动态组件
						     动态的切换component 的is输出的模板 ？
示例:
<body>
    <div id="box" @click="type='no2'">
        <componentis="type">
        </componentis=>
    </div>
</body>

<script src="../js/vue.js"></script>
<!-- <scrip> -->
    //动态组件
    //动态的切换component 的is输出的模板
    Vue.component('no1',{
        template:'<p> this is no1 </p>',
        data(){
            return{
               
            }
        }
    })
    Vue.component('no2',{
        template:'<p> this is no2 </p>'
    })
    new Vue({
        el:'#box',
        data:{
            a:1,
            type:'no1'
        }
    })
<!-- </script> -->

---------------------------------------------------------------------------------------------------组件传值 
父 传 子
      props 是只读状态  不可修改    
      如果需要操作props 传入的值需要再data中重新定义  return 

 子传父
       自定义事件 $emit

 兄弟传
        let bus = new Vue()
        1 
            bus.$emit('name',data)
        2
            mounted()
            bus.$on('name',(data)=>{})
-----------------------------------------------------------------------------------------------------插槽 
插槽是什么？怎么用？
插槽slot， 是组件中的一块html模板，模板显示不显示，以及怎样显示由父组件来决定。
插槽的使用场景。当父组件中想要操作子组件，往子组件插入html代码片段的时候，这时候插槽的作用就是体现了
如果子组件不设置插槽，父组件是插入不了子组件中的代码片段的。
 三个插槽--
                匿名插槽，命名插槽，作用域插槽

//匿名插槽

    <p></p>
    <slot></slot>		     
//命名插槽		    
     //元素有一个特殊的特性：name用来定义额外的插槽。一个不带 name 的 出口会带有隐含的名字“default”
           <p slot = "name" ></p>           //具名插槽使用场景：一个模版需要多个插槽。
           <slot name ="name" ></slot>
//作用域插槽。。


参考上面博客......
//博客https://blog.csdn.net/qq_46124502/article/details/107261997?biz_id=102&utm_term

-------------------------------------------------------------------- ------------------------路由
vue-router是基于路由和组件的
路由用于设定访问路径, 将路径和组件映射起来.
在vue-router的单页面应用中, 页面的路径的改变就是组件的切换.
vue-router的实现原理 更新视图而不重新加载请求页面

.$route和 $router的区别是什么？
    $router为VueRouter的实例，是一个全局路由对象，包含了路由跳转的方法、钩子函数等。
    $route 是路由信息对象||跳转的路由对象，每一个路由都会有一个route对象，是一个局部对象，包含path,params,hash,query,fullPath,matched,name等路由信息参数。


vue-router有哪几种路由守卫?
路由守卫为：
全局守卫：beforeEach
后置守卫：afterEach
全局解析守卫：beforeResolve
路由独享守卫：beforeEnter


前端路由？
路由之间跳转
声明式（标签跳转） 
<router link="...."> vue 提供    URL的hash：URL的hash也就是锚点(#), 本质上是改变window.location的href属性.
			 通过直接赋值location.hash来改变href, 但是页面不发生刷新
编程式（ js跳转）
事件触发 this.router.push("/")  this.router.go('1') 用于返回上一个页面  
window.history.back()           返回到上一个页面
window.history.forward()        进入到下一个页面
window.history.go([delta])      跳转到指定页面
pushState是往history            对象里添加一个新的历史记录，即压栈。
replaceState 是替换history      对象中的当前历史记录。

---------------------------------------------------------------------------------------------vue-router响应路由参数的变化
方法一*用watch 检测
vue-router响应路由参数的变化
	监听路由发生变化的时候执行
	watch：{
		$route(to,from){
		console.log(to.path)	  //对路由变化做出响应 	
	}}

方法2*组件内导航钩子函数 导航守卫
	beforeRouteUpdate(to,from,next){
	             //to do somethings
	}
       
----------------------------------------------------------------------------------------------keep-alive
     vue 路由 按需 keep-alive
     把需要缓存和不需要缓存的视图组件区分开
----------------------------------------------------------------------------------------------动态路由
// 路由导航功能是不能传递参数的，也就是说是--->静态路由。
// 能传递参数的路由模式，由于可以传递参数，所以其对应的路由数量是不确定的动态路由


query'params区别
              *Params
+	只能使用name，不能使用path ---参数不会显示在路径上---浏览器强制刷新参数会被清空
                //传递参数 
	this.$router.push({   
	 		name: Home,
			params:{ 
                number: 1 ,
                code:"123"}
		             })
	//接受参数
	const p = this.$touter.params 

+               *Query
	参数会显示在路径上，刷新不会被清空---name 可以使用path路径
	this.$router.push({
			name: Home,
			query:{
                number: 1,
                code: "456"
			}})
	//接受参数 
	const q = this.$router.query 
  
  params的类型: 动态路由中也用到params
	配置路由格式: /router/:id
	传递的方式: 在path后面跟上对应的值
	传递后形成的路径:/router/123, /router/abc

   query的类型:
	配置路由格式:/router, 也就是普通配置传递的方式:
	对象中使用query的key作为传递方式
	传递后形成的路径: /router?id=123, /router?id=abc


///当我们需要传大量 的数据的时候，用query的方式。
///需要传一个，或者少量的数据的时候，用params


// 	定义动态路由： 
//             在参数名前面加上 ，然后将参数写在路由的 path 内

//     ----------------------------具体操纵
// 如下示例：
//  routes: [
//     //将页面组件与path指令的路由关联
//     { name: 'BookInfo', path: '/books/:id', component: BookInfo }
//   ]
// 在<router-link> 我们加入一个 params 属性来指定具体的参数值
//    <li>
//         <router-linkto ="{name:'BookInfo',params{id:1}}" >
//            <div>首页</div>
//         </router-linkto>                        
//        </li>

//    ----------------------------多个参数
// 如果需要传入多个参数值，只要按照上面的命名方法来加入参数，
// 传递在params中对应的声明参数值即可，vue-router只要匹配到路由模式的定义就会自动对参数进行分解取值
//    如 path: '/books/version/:id'，
//    则对应params为：params{id:1,version:1}

//    ----------------------------读取参数(如何从路由中将这个参数值读取出来呢？把它输出到页面上)
// 通过 $route.params属性获取指定的参数值，
//    如：this.$route.params.id,
//           this.$route.params.msg

//   -----------------------------输出参值(在相应的组件页面内输出参数值，对应代码如下： )
//   <p>当前图书编号是：{{$route.params.id}}</p> 
-----------------------------------------------------------------------------------------------------------------------------
补充知识点
       methods:{
	linkhome(){
		//this.$router('/home')             push可以返回的跳转
		this.$router.replact('/home')    replace不可以返回的跳转
	}
}
	
-------------------------------------------------------------------------webpack
cnpm i webpack webpack-cli webpack-dev-server -g

打包
    vue react (mvvm)
        环境开发-》webpack-》node
    
打包js
其他文件，需要配置loader（加载器）

打包模式
    development  开发环境 打包时间短 文件大
    production     生成环境 打包时间长 文件小

指令 
    webpack --mode=development
    webpack --mode=production
https://blog.csdn.net/qq_36660558/article/details/81054334
真实打包完成的 （你看到他已经输出的一个文件）
服务器状态下的模拟打包 
 

----------------------------------------------------------------------------------cli 
vue 不适合写官网之类东西      
          适合管理系统

nuxt 服务器渲染  
cnpm i vue-cli -g     vue init simple app
 
cli2 
  simple                     vue init simple app           太简单
  webpck                     vue init webpack app          太繁琐
  webpack-simple             vue init webpack-simple app   适中的
cli3
   把webpack封装 
   可以直接操作cli 提供的配置

-------------------------------------------------------------------------------------
    
es6 的引入和暴露
暴露
    1 export default {}
    2 export {
        a:12,
        b:23
    }
引入
    1 import name  from './path'     导入模块import***from***是es6     import模块名称from是路径
    2 import {a,b} from './path'        按需导入   
      import './name'


export default 向外暴露的成员，可以使用任意变量来接收
在一个模块中，export default 只准许向外暴漏一次
	       可以同时使用export default 和 export 向外暴露成员
	       使用export 向外暴露成员只可以使用 {} 象形式接受  这种形式叫[按需导入]
           使用export 导出的成员 ，必须严格按照导出时的名称 ，来使用{} 按需接收

-------------------------------------------------------------------------  vue  X
状态管理模式
	;以简单的将其看成把需要多个组件共享的变量全部存储在一个对象里面。

使用场景  ？
	多个视图使用于同一状态       -->传参的方法对于多层嵌套的组件将会非常繁琐，并且对于兄弟组件间的状态传递无能为力
	不同视图需要变更同一状态     -->采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝，通常会导致无法维护的代码

vue x 状态管理器   
        state       放初始化状态
        getter      类似计算属性computed 计算后输出
        mutation    修改state状态的唯一方法  对内不对外
        action      类型于methods  	对外不对内    用来派发mutation而不是直接变更状态 action可以可以包含任意异步操作

获取
	1直接输出
	2计算之后输出
-------------------------------------------------------------------------------------环境开发全局使用功能件儿
  全局使用  组件 过滤器 自定义指令...
  import but from ' ./.././/'
let index = {
	install(Vue){
	    Vue.component('but',but)
     }
}
export default index   //暴露出去

在上面地方用
import index from './../路径
Vue.use(index)





在任意vue文件中写全局函数
1创建全局方法
this.$root.$on("text",function(){
	console.log("111111111")
}
2销毁全局方法
this.$root.$off("text")
3调用全局方法
this.$root.$emit("text")


------------------------------------------------------------------------------------------------真机测试？
1  ipconfig 输入命令行
2  然后在webpack.config.js  里面找到 devServer 里面添加   IPv4 地址 . . . . . . . . . . . . 192.168.43.247

------------------------------------------------------------------------------------------------懒加载使用
https://aqingya.cn/articl/6f59ac64.html   博客

1 cnpm install vue-lazyload --save-dev命令行下载
2 npm下载安装成功后，在main.js内注册	
  import VueLazyLoad from 'vue-lazyload'
  Vue.use(VueLazyLoad, {
      error:'/static/error.png',
     loading: '/static/loading.png'
   })
3需要懒加载的图片  vue文件中将需要懒加载的图片绑定 v-bind:src 修改为 v-lazy
 <img v-lazy="图片地址" alt="">
https://www.cssportal.com/css3-color-names/


------------------------------------------------------------------------------------------------add animation 工具
1 cnpm i animated.css@3.5.1 --save   命令行
2 在ming.js 输入
   import animated from 'animate.css'    // npm install animate.css --save安装，在引入
   Vue.use(animated)
3  <div><p @click="move" ref='out'>222222222222
22222222222222222222</p></div>
	在methods 写 
             move:function(){
                    console.log(this.$refs.out)
                    this.$refs.out.className = 'animated fadeOutRight '
                },

 4 https://animate.style/ 官网	
 5 拓展--https://www.cssportal.com/css3-box-shadow-generator/
--------------------------------------------------------------------------------jq  bootstarp
1 npm install jquery  --save

2 npm install bootstrap --save 
  //或者安装特定的版本 npm install bootstrap@4.0.0-beta.2
    如果安装的是4.0的版本还需要 npm install --save popper.js

3 第二步: 修改build\webpack.base.conf.js
  alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'assets': path.resolve(__dirname, '../src/assets'),
      'jquery': "jquery/src/jquery"
    }
	
  plugins: [
  new webpack.ProvidePlugin({
     $:"jquery",
     jQuery:"jquery",
    "windows.jQuery":"jquery" //如果安装了Popperjs就还需要添加 Popper: ['popper.js', 'default']
  })
],

第三步修改主程序js文件,一般是main.js或者是index.js，添加如下代码
   import jquery from 'jquery'
   import 'bootstrap/dist/css/bootstrap.min.css'
   import 'bootstrap/dist/js/bootstrap.min.js'
   import " popper.js/dist/umd/popper.min.js " ;
	
到这里bootstrap就引入完成了.jquery必须在bootstrap之前,因为bootstrap依赖于jq库.!
------------------------------------------------------------------打包项目
2.0  
   1 在webpack.config.js  里面 pulibpath 加 .
     打包在 index.html 路径加 . 
     

3.0 在 根目录下 
    1vue.config.js
	module.exports = {
    publicPath: './'
      }
   去路由里面注释 history 
-------------------------------------------------------------------scss in vue 
.如何引入scss?引入后如何使用？
安装scss依赖包：npm install sass-loader --save-dev npm install node-sass --save-dev
在build文件夹下修改 webpack.base.conf.js 文件，在 module 下的 rules 里添加配置，如下：
{ test: /\.scss$/, loaders: ['style', 'css', 'sass'] }
应用：在vue文件中应用scss时，需要在style样式标签上添加lang="scss"，即<style lang="scss">
    */
